package com.nononsenseapps.feeder.ui

import android.content.Intent
import android.net.Uri
import android.view.View
import android.widget.ImageView
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
import androidx.recyclerview.widget.RecyclerView
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import com.nononsenseapps.feeder.db.TestDatabaseRule
import com.nononsenseapps.feeder.db.URI_FEEDS
import com.nononsenseapps.feeder.db.entity.Feed
import com.nononsenseapps.feeder.db.entity.FeedItem
import com.nononsenseapps.feeder.mobile.ui.FeedActivity
import com.nononsenseapps.feeder.util.PrefUtils
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import java.net.URL

@RunWith(AndroidJUnit4::class)
@LargeTest
class BadImagePlaceHolderTest {
    @get:Rule
    var activityRule: ActivityTestRule<FeedActivity> = ActivityTestRule(FeedActivity::class.java, false, false)

    @get:Rule
    val testDb = TestDatabaseRule(getApplicationContext())

    private val server = MockWebServer()

    @After
    fun stopServer() {
        server.shutdown()
    }

    @Test
    fun placeHolderIsShownOnBadImageNightTheme() {
        PrefUtils.setNightMode(getApplicationContext(), true)
        AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES)
        placeHolderIsShownOnBadImage()
    }

    @Test
    fun placeHolderIsShownOnBadImageDayTheme() {
        PrefUtils.setNightMode(getApplicationContext(), false)
        AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO)
        placeHolderIsShownOnBadImage()
    }

    private fun placeHolderIsShownOnBadImage() {
        server.enqueue(MockResponse().also {
            it.setResponseCode(400)
        })
        server.start()

        val imgUrl = server.url("/img.png")

        val feedId = testDb.db.feedDao().insertFeed(
            Feed(
                title = "foo",
                url = URL("http://foo")
        )
        )

        testDb.db.feedItemDao().insertFeedItem(
            FeedItem(
                guid = "bar",
                feedId = feedId,
                title = "foo",
                imageUrl = "$imgUrl"
        )
        )

        activityRule.launchActivity(Intent(Intent.ACTION_VIEW, Uri.withAppendedPath(URI_FEEDS, "$feedId")))

        runBlocking {
            delay(50)

            val recyclerView = activityRule.activity.findViewById<RecyclerView>(android.R.id.list)!!
            val viewHolder = recyclerView.findViewHolderForAdapterPosition(0)!!
            val imageView = viewHolder.itemView.findViewById<ImageView>(R.id.story_image)!!

            withTimeout(10000) {
                while (true) {
                    if (imageView.visibility == View.VISIBLE && imageView.drawable != null) {
                        break // good
                    }
                    delay(50)
                }
            }
        }

        onView(withId(R.id.story_image)).check(matches(isDisplayed()))
    }
}
